/* This traverses the abstract syntax tree. */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Ast.h"
#include "Symtab.h"
#include "BaseMining.h"
#define MAX_DIGITS 20



struct symbol_table *newnode;
//BaseMining e;
BaseMining *m = NULL;
NODE *basenode = NULL;
bool bw, func_ref, proj, atmop=0, exp=0;
char *opcarray[10] ; 
char *cname = NULL, *opcname = NULL, *funcname=NULL;
void *cfilter = NULL;	
MINEOPERATOR optr, optrarray[10], logicarry[10];
int n = 0, total, logiccounter = 0, counter = 1, optf = 0, i=0, j=0, boolop=0, bc;
long int r1 = -1, r2 = -1;   
char str[MAX_DIGITS+1];
bool is_vardec_list = false;
void pop();


void visitStatement(Statement _p_)
{
  BaseMining::init();
  switch(_p_->kind)
  {
  case is_Stmt:
    /* Code for Stmt Goes Here */
    printf("\nEnter the number of Conditional Boolean Operators you have entered :\t");
    scanf("%d",&bc);	
    total = bc+bc+1;
    if (bc > 0)
    	{
    	printf("\nEnter 1 for display in Postfix Else Enter 0 for Infix :\t");
    	scanf("%d",&exp);
	}
    visitQuery(_p_->u.stmt_.query_);
    visitSc(_p_->u.stmt_.sc_);
    //display_table();
    m->displayProjection();
    BaseMining::cleanUp();		
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Statement!\n");
    exit(1);
  }
  
  free_table();
}

void visitQuery(Query _p_)
{
  switch(_p_->kind)
  {
  case is_Qry:
    /* Code for Qry Goes Here */
    visitSelect(_p_->u.qry_.select_);
    visitSpecifier(_p_->u.qry_.specifier_);
    is_vardec_list = false;
    visitVariable_declaration_list(_p_->u.qry_.variable_declaration_list_);	
    visitProjection_list(_p_->u.qry_.projection_list_);	
    visitFrom(_p_->u.qry_.from_);
    visitOptional_Where_Clause(_p_->u.qry_.optional_where_clause_);
    visitOptional_Group_By_Clause(_p_->u.qry_.optional_group_by_clause_);
    visitOptional_Having_Clause(_p_->u.qry_.optional_having_clause_);
    visitOptional_Order_By_Clause(_p_->u.qry_.optional_order_by_clause_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Query!\n");
    exit(1);
  }
}

void visitSpecifier(Specifier _p_)
{
  switch(_p_->kind)
  {
  case is_Nospe:
    /* Code for Nospe Goes Here */
    break;
  case is_Distn:
    /* Code for Distn Goes Here */
    visitDistinct(_p_->u.distn_.distinct_);
    visitSpecifier(_p_->u.distn_.specifier_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Specifier!\n");
    exit(1);
  }
}

void visitProjection_list(Projection_list _p_)
{
	proj = true;
	BaseMining *mining_instance = NULL;
  struct object_chain *temp = NULL;
  struct symbol_table *latest = NULL;	
  switch(_p_->kind)
  {
   	
  case is_Prj:
    /* Code for Prj Goes Here */
    visitProjection(_p_->u.prj_.projection_);
	
    break;
  case is_Prjlist:
    /* Code for Prjlist Goes Here */
    visitProjection_list(_p_->u.prjlist_.projection_list_);
    proj = true;
    visitProjection(_p_->u.prjlist_.projection_);
	 
    break;
  case is_Strprj:
    if(is_vardec_list == true)
    	{
    		fprintf(stderr, "Error! Star projection not allowed for multiple tables.");
    		BaseMining::cleanUp();
    		free_table();
    		exit(1);
    	}
    	latest = return_last_node();
    	if(latest->ptr == NULL)
    	{
    		fprintf(stderr, "Variable declaration with no object chain!");
    		BaseMining::cleanUp();
    		free_table();
    		exit(1);
    	}
    	temp = latest->ptr;
    	while(temp->next != NULL)
    		temp = temp->next;
    	mining_instance = BaseMining::getMiningInstance(temp->object_name);
    	if(mining_instance == NULL)
    	{
    		fprintf(stderr, "\nNo table with name %s\n", temp->object_name);
    		BaseMining::cleanUp();
    		free_table();
    		exit(1);
    	}
    	
    	mining_instance->setProjectionsAll();
	   	break;
 
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Projection_list!\n");
    exit(1);
  }
  proj = false;
}

void visitProjection(Projection _p_)
{
	
  switch(_p_->kind)
  {
  case is_Idprj:
    newnode = make_node();
    if(add_variable_name(newnode, _p_->u.idprj_.identifier_) == 0)
    {
    	printf("\nRedeclaration of variable name %s\n",_p_->u.idprj_.identifier_);
    	exit(1);
    }
    visitIdentifier(_p_->u.idprj_.identifier_);
    visitReference(_p_->u.idprj_.reference_);
    m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    if(m == NULL)
    {
    	printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    cname = m->verify(newnode->ptr->next, proj, funcname);
    if(cname != NULL)
    {
    	printf("\n%s not a valid column name.\n", cname);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    add_node(newnode);
    newnode = NULL;
    break;
  case is_Asprj:
    newnode = make_node();
    if(add_variable_name(newnode, _p_->u.asprj_.identifier_) == 0)
    {
    	printf("\nRedeclaration of variable name %s\n",_p_->u.asprj_.identifier_);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    visitReference(_p_->u.asprj_.reference_);
    m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    if(m == NULL)
    {
    	printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    cname = m->verify(newnode->ptr->next, proj, funcname);
    if(cname != NULL)
    {
    	printf("\n%s not a valid column name.\n", cname);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    //projections[count] = newnode->ptr->object_name;
    //count = count + 1;		
    //opcname = newnode->ptr->object_name;	
    visitAs(_p_->u.asprj_.as_);
    visitIdentifier(_p_->u.asprj_.identifier_);
    add_node(newnode);
    newnode = NULL;
    break;
  case is_Plusprj:
    /* Code for Plusprj Goes Here */
    visitProjection(_p_->u.plusprj_.projection_1);
    visitProjection(_p_->u.plusprj_.projection_2);
    break;
  case is_Minprj:
    /* Code for Minprj Goes Here */
    visitProjection(_p_->u.minprj_.projection_1);
    visitProjection(_p_->u.minprj_.projection_2);
    break;
  case is_Mulprj:
    /* Code for Mulprj Goes Here */
    visitProjection(_p_->u.mulprj_.projection_1);
    visitProjection(_p_->u.mulprj_.projection_2);
    break;
  case is_Divprj:
    /* Code for Divprj Goes Here */
    visitProjection(_p_->u.divprj_.projection_1);
    visitProjection(_p_->u.divprj_.projection_2);
    break;
  case is_Modprj:
    /* Code for Modprj Goes Here */
    visitProjection(_p_->u.modprj_.projection_1);
    visitMod(_p_->u.modprj_.mod_);
    visitProjection(_p_->u.modprj_.projection_2);
    break;
  case is_Refprj:
    visitReference(_p_->u.refprj_.reference_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Projection!\n");
    exit(1);
  }
}

void visitReference(Reference _p_)
{
  switch(_p_->kind)
  {
  case is_Colref:
    if(newnode == NULL)
    {
    	newnode = make_node();
    	if(add_variable_name(newnode, "") == 0)
    	{
    		printf("\nProblem adding column reference to symbol table.");
    		free(newnode);
    		free_table();
    		exit(1);
    	}
    	visitColumn_Reference(_p_->u.colref_.column_reference_);
    	m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    	if(m == NULL)
   	{
    		printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    		free(newnode);
    		free_table();
    		exit(1);
    	}
    	cname = m->verify(newnode->ptr->next, proj, funcname);
    	if(cname != NULL)
    	{
    		printf("\n%s not a valid column name.\n", cname);
    		free(newnode);
    		free_table();
    		exit(1);
    	}
        opcname = newnode->ptr->next->object_name;
	opcarray[i]=opcname;
	++i;
	/*if (func_ref)
		cname = m->verify(newnode->ptr->next, proj, funcname);
		if(cname != NULL)
    		{
    			printf("\n%s Not a valid operation.\n", funcname);
    			free(newnode);
    			free_table();
    			exit(1);
    		}	*/
       	add_node(newnode);
    	newnode = NULL;
    }
    else
    {
    	visitColumn_Reference(_p_->u.colref_.column_reference_);
    }
    break;
  case is_FuncRef:
    /* Code for FuncRef Goes Here */
    visitFunction_Reference(_p_->u.funcref_.function_reference_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Reference!\n");
    exit(1);
  }
}

void visitColumn_Reference(Column_Reference _p_)
{
  switch(_p_->kind)
  {
  case is_Name:
    if(newnode != NULL)
    {
    	struct symbol_table *temp = check_variable_name(_p_->u.name_.identifier_);
    	if(temp != NULL)
    	{
    		replicate_object_chain(temp->ptr, newnode);
    	}
    	else
    	{
    		add_object_name(newnode, _p_->u.name_.identifier_);
    	}
    }
    visitIdentifier(_p_->u.name_.identifier_);
    break;
  case is_Namenst:
    visitColumn_Reference(_p_->u.namenst_.column_reference_);
    visitDot(_p_->u.namenst_.dot_);
    if(newnode != NULL)
    {
    	add_object_name(newnode, _p_->u.namenst_.identifier_);
    }
    visitIdentifier(_p_->u.namenst_.identifier_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Column_Reference!\n");
    exit(1);
  }
}

void visitFunction_Reference(Function_Reference _p_)
{
  func_ref=1; 	
  switch(_p_->kind)
  {
  case is_FuncCnt:
    /* Code for FuncCnt Goes Here */
    visitCount(_p_->u.funccnt_.count_);
    func_ref=0;	
    break;
  case is_FuncCntDst:
    /* Code for FuncCntDst Goes Here */
    visitCount(_p_->u.funccntdst_.count_);
    visitDistinct(_p_->u.funccntdst_.distinct_);
    visitColumn_Reference(_p_->u.funccntdst_.column_reference_);
    func_ref=0;	
    break;
  case is_FuncCntSca:
    /* Code for FuncCntSca Goes Here */
    visitCount(_p_->u.funccntsca_.count_);
    visitScalar_Exp(_p_->u.funccntsca_.scalar_exp_);
    func_ref=0;	  
    break;
  case is_FuncScaDst:
    /* Code for FuncScaDst Goes Here */
    visitFunction(_p_->u.funcscadst_.function_);
    visitDistinct(_p_->u.funcscadst_.distinct_);
    visitColumn_Reference(_p_->u.funcscadst_.column_reference_);
    func_ref=0;	    
    break;
  case is_FuncSca:
    /* Code for FuncSca Goes Here */
    visitFunction(_p_->u.funcsca_.function_);
    visitScalar_Exp(_p_->u.funcsca_.scalar_exp_);
    func_ref=0;	 
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Function_Reference!\n");
    exit(1);
  }
  funcname = NULL;
}

void visitFunction(Function _p_)
{
  switch(_p_->kind)
  {
  case is_FuncSum:
    /* Code for FuncSum Goes Here */
    visitSum(_p_->u.funcsum_.sum_);
    break;
  case is_FuncAvg:
    /* Code for FuncAvg Goes Here */
    visitAvg(_p_->u.funcavg_.avg_);
    break;
  case is_FuncMax:
    /* Code for FuncMax Goes Here */
    visitMax(_p_->u.funcmax_.max_);
    break;
  case is_FuncMin:
    /* Code for FuncMin Goes Here */
    visitMin(_p_->u.funcmin_.min_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Function!\n");
    exit(1);
  }
}

void visitDot(Dot _p_)
{
  switch(_p_->kind)
  {
  case is_Dt:
    /* Code for Dt Goes Here */
    break;
  case is_Ptr:
    /* Code for Ptr Goes Here */
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Dot!\n");
    exit(1);
  }
}

void visitVariable_declaration_list(Variable_declaration_list _p_)
{
  switch(_p_->kind)
  {
  case is_Vardec:
    /* Code for Vardec Goes Here */
    visitVariable_declaration(_p_->u.vardec_.variable_declaration_);
    break;
  case is_Vardeclist:
    /* Code for Vardeclist Goes Here */
    visitVariable_declaration_list(_p_->u.vardeclist_.variable_declaration_list_);
    visitVariable_declaration(_p_->u.vardeclist_.variable_declaration_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Variable_declaration_list!\n");
    exit(1);
  }
}

void visitVariable_declaration(Variable_declaration _p_)
{
  switch(_p_->kind)
  {
  case is_Colrfas:
    newnode = make_node();
    if(add_variable_name(newnode, _p_->u.colrfas_.identifier_) == 0)
    {
    	printf("\nRedeclaration of variable name %s\n", _p_->u.colrfas_.identifier_);
    	exit(1);
    }
    visitColumn_Reference(_p_->u.colrfas_.column_reference_);
    m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    if(m == NULL)
    {
    	printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    cname = m->verify(newnode->ptr->next, proj, funcname);
    if(cname != NULL)
    {
    	printf("\n%s not a valid column name.\n", cname);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    opcname = newnode->ptr->next->object_name;
    opcarray[i] = opcname;
    ++i;		
    visitAs(_p_->u.colrfas_.as_);
    visitIdentifier(_p_->u.colrfas_.identifier_);
    add_node(newnode);
    newnode = NULL;
    break;
  case is_Colrfin:
    newnode = make_node();
    if(add_variable_name(newnode, _p_->u.colrfin_.identifier_) == 0)
    {
    	printf("\nRedeclaration of variable name %s\n", _p_->u.colrfin_.identifier_);
    	exit(1);
    }
    visitIdentifier(_p_->u.colrfin_.identifier_);
    visitIn(_p_->u.colrfin_.in_);
    visitColumn_Reference(_p_->u.colrfin_.column_reference_);
    m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    if(m == NULL)
    {
     	printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    cname = m->verify(newnode->ptr->next, proj, funcname);
    if(cname != NULL)
    {
    	printf("\n%s not a valid column name.\n", cname);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    //opcname = newnode->ptr->next;
    add_node(newnode);
    newnode = NULL;
    break;
  case is_Colrf:
    if(newnode != NULL)
    {
    	printf("\nEntering column reference with an unattached node.\n");
    	exit(1);
    }
    newnode = make_node();
    if(add_variable_name(newnode, "") == 0)
    {
    	printf("\nProblem adding column reference to symbol table.");
    	free(newnode);
    	free_table();
    	exit(1);
    }
    	
    visitColumn_Reference(_p_->u.colrf_.column_reference_);
    m = BaseMining::getMiningInstance(newnode->ptr->object_name);
    if(m == NULL)
    {
    	printf("\n%s not a valid table name.\n", newnode->ptr->object_name);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    cname = m->verify(newnode->ptr->next, proj, funcname);
    if(cname != NULL)
    {
    	printf("\n%s not a valid column name.\n", cname);
    	free(newnode);
    	free_table();
    	exit(1);
    }
    opcname = newnode->ptr->next->object_name;
    opcarray[i] = opcname;
    ++i;				
    add_node(newnode);
    newnode = NULL;
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Variable_declaration!\n");
    exit(1);
  }
}

void visitOptional_Where_Clause(Optional_Where_Clause _p_)
{
  switch(_p_->kind)
  {
  case is_NoWhr:
    /* Code for NoWhr Goes Here */
    break;
  case is_WhrCl:
    /* Code for WhrCl Goes Here */
    visitWhere(_p_->u.whrcl_.where_);
    visitCondition(_p_->u.whrcl_.condition_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Optional_Where_Clause!\n");
    exit(1);
  }
}

void visitCondition(Condition _p_)
{
  switch(_p_->kind)
  {
  case is_AndCnd:
    /* Code for AndCnd Goes Here */
    
    visitCondition(_p_->u.andcnd_.condition_1);
    visitAnd(_p_->u.andcnd_.and_);
    visitCondition(_p_->u.andcnd_.condition_2);
    if (exp)	 
    	pop();	 
    break;
  case is_OrCnd:
    /* Code for OrCnd Goes Here */
    
    visitCondition(_p_->u.orcnd_.condition_1);
    visitOr(_p_->u.orcnd_.or_);
    visitCondition(_p_->u.orcnd_.condition_2);
    if (exp)	 
    	pop(); 	
    break;
  case is_NotCnd:
    /* Code for NotCnd Goes Here */
     m->setFilter1(NULL, OP_NOT, NULL, total, logiccounter);	
     visitNot(_p_->u.notcnd_.not_);
     visitCondition(_p_->u.notcnd_.condition_);
     if (exp)	 
    	pop();	
    break;
  case is_PredCnd:
    /* Code for PredCnd Goes Here */
    visitPredicate(_p_->u.predcnd_.predicate_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Condition!\n");
    exit(1);
  }
}

void visitPredicate(Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_CmpPred:
    /* Code for CmpPred Goes Here */
    visitComparison_Predicate(_p_->u.cmppred_.comparison_predicate_);
    break;
  case is_InPred:
    /* Code for InPred Goes Here */
    visitIn_Predicate(_p_->u.inpred_.in_predicate_);
    break;
  case is_BetPred:
    /* Code for BetPred Goes Here */
    visitBetween_Predicate(_p_->u.betpred_.between_predicate_);
    break;
  case is_ExstPred:
    /* Code for ExstPred Goes Here */
    visitExists_Predicate(_p_->u.exstpred_.exists_predicate_);
    break;
  case is_LikePred:
    /* Code for LikePred Goes Here */
    visitLike_Predicate(_p_->u.likepred_.like_predicate_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Predicate!\n");
    exit(1);
  }
}

void visitComparison_Predicate(Comparison_Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_CompSca:
    /* Code for CompSca Goes Here */
    visitScalar_Exp(_p_->u.compsca_.scalar_exp_1);
    visitComparison(_p_->u.compsca_.comparison_);
    visitScalar_Exp(_p_->u.compsca_.scalar_exp_2);
    
    break;
  case is_CompNstQry:
    /* Code for CompNstQry Goes Here */
    visitScalar_Exp(_p_->u.compnstqry_.scalar_exp_);
    visitComparison(_p_->u.compnstqry_.comparison_);
    visitNested_Query(_p_->u.compnstqry_.nested_query_);
   
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Comparison_Predicate!\n");
    exit(1);
  }
}

void visitIn_Predicate(In_Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_InNstQry:
    /* Code for InNstQry Goes Here */
    visitScalar_Exp(_p_->u.innstqry_.scalar_exp_);
    visitIn(_p_->u.innstqry_.in_);
    visitNested_Query(_p_->u.innstqry_.nested_query_);
    break;
  case is_NotInNstQry:
    /* Code for NotInNstQry Goes Here */
    visitScalar_Exp(_p_->u.notinnstqry_.scalar_exp_);
    visitNot(_p_->u.notinnstqry_.not_);
    visitIn(_p_->u.notinnstqry_.in_);
    visitNested_Query(_p_->u.notinnstqry_.nested_query_);
    break;
  case is_InAtmList:
    /* Code for InAtmList Goes Here */
    visitScalar_Exp(_p_->u.inatmlist_.scalar_exp_);
    visitIn(_p_->u.inatmlist_.in_);
    visitAtom_List(_p_->u.inatmlist_.atom_list_);
    break;
  case is_NotInAtmList:
    /* Code for NotInAtmList Goes Here */
    visitScalar_Exp(_p_->u.notinatmlist_.scalar_exp_);
    visitNot(_p_->u.notinatmlist_.not_);
    visitIn(_p_->u.notinatmlist_.in_);
    visitAtom_List(_p_->u.notinatmlist_.atom_list_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing In_Predicate!\n");
    exit(1);
  }
}

void visitBetween_Predicate(Between_Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_BetScaExp:
    /* Code for BetScaExp Goes Here */
    bw=1;	
    visitScalar_Exp(_p_->u.betscaexp_.scalar_exp_1);
    visitBetween(_p_->u.betscaexp_.between_);
    visitScalar_Exp(_p_->u.betscaexp_.scalar_exp_2);
    visitAnd(_p_->u.betscaexp_.and_);
    visitScalar_Exp(_p_->u.betscaexp_.scalar_exp_3);
    if (exp)	 
    	pop(); 
    bw=0;	
    break;
  case is_NotBetScaExp:
    /* Code for NotBetScaExp Goes Here */
    bw=1;	
    visitScalar_Exp(_p_->u.notbetscaexp_.scalar_exp_1);
    visitNot(_p_->u.notbetscaexp_.not_);
    visitBetween(_p_->u.notbetscaexp_.between_);
    visitScalar_Exp(_p_->u.notbetscaexp_.scalar_exp_2);
    visitAnd(_p_->u.notbetscaexp_.and_);
    visitScalar_Exp(_p_->u.notbetscaexp_.scalar_exp_3);
    if (exp)	 
    	pop();
    bw=0; 
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Between_Predicate!\n");
    exit(1);
  }
}

void visitLike_Predicate(Like_Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_LkStr:
    /* Code for LkStr Goes Here */
    visitScalar_Exp(_p_->u.lkstr_.scalar_exp_);
    visitLike(_p_->u.lkstr_.like_);
    visitString(_p_->u.lkstr_.string_);
    break;
  case is_NotLkStr:
    /* Code for NotLkStr Goes Here */
    visitScalar_Exp(_p_->u.notlkstr_.scalar_exp_);
    visitNot(_p_->u.notlkstr_.not_);
    visitLike(_p_->u.notlkstr_.like_);
    visitString(_p_->u.notlkstr_.string_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Like_Predicate!\n");
    exit(1);
  }
}

void visitExists_Predicate(Exists_Predicate _p_)
{
  switch(_p_->kind)
  {
  case is_ExstQry:
    /* Code for ExstQry Goes Here */
    visitExists(_p_->u.exstqry_.exists_);
    visitNested_Query(_p_->u.exstqry_.nested_query_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Exists_Predicate!\n");
    exit(1);
  }
}

void visitAtom_List(Atom_List _p_)
{
  switch(_p_->kind)
  {
  case is_SglAtmLst:
    /* Code for SglAtmLst Goes Here */
    visitAtom(_p_->u.sglatmlst_.atom_);
    break;
  case is_MulAtmLst:
    /* Code for MulAtmLst Goes Here */
    visitAtom_List(_p_->u.mulatmlst_.atom_list_);
    visitAtom(_p_->u.mulatmlst_.atom_);
    break;


  default:
    fprintf(stderr, "Error: bad kind field when printing Atom_List!\n");
    exit(1);
  }
}

void visitNested_Query(Nested_Query _p_)
{
  switch(_p_->kind)
  {
  case is_NstQry:
    /* Code for NstQry Goes Here */
    visitQuery(_p_->u.nstqry_.query_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Nested_Query!\n");
    exit(1);
  }
}

void visitScalar_Exp(Scalar_Exp _p_)
{
	bool flag = false;
  switch(_p_->kind)
  {
  case is_AndSca:
    optr = OP_BAND;
    if((_p_->u.andsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.andsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_BAND;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    visitScalar_Exp(_p_->u.andsca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.andsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.andsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_BAND;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.andsca_.scalar_exp_2);
    if(!flag)
    {
    	optrarray[j] = OP_BAND;
    	++j; 		
    	optf = optf + 1;   	
    }
    break;
  case is_OrSca:
     /* Code for OrSca Goes Here */
    optr = OP_BOR;
    if((_p_->u.orsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.orsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_BOR;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.orsca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.andsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.andsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_BOR;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.orsca_.scalar_exp_2);
    if(!flag)
	{
	    optrarray[j] = OP_BOR;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    break;
  case is_XorSca:
    /* Code for XorSca Goes Here */
    optr =OP_XOR;
    if((_p_->u.xorsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.xorsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_XOR;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.xorsca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.xorsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.xorsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_XOR;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.xorsca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_XOR;
    	++j; 		 
    	optf = optf + 1;
    }    
    break;
  case is_LsSca:
    /* Code for LsSca Goes Here */
    optr = OP_LS;
    if((_p_->u.lssca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.lssca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_LS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.lssca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.lssca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.lssca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_LS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.lssca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_LS;
    	++j; 		
    	optf = optf + 1;
    }
    
    break;
  case is_RsSca:
    /* Code for RsSca Goes Here */
    optr = OP_RS;
    if((_p_->u.rssca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.rssca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_RS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.rssca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.rssca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.rssca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_RS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.rssca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_RS;
    	++j; 		
    	optf = optf + 1;		
    }
    
    break;
  case is_PlusSca:
    /* Code for PlusSca Goes Here */
    optr = OP_PLUS;
    if((_p_->u.plussca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.plussca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_PLUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.plussca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.plussca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.plussca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_PLUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.plussca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_PLUS;
    	++j; 		
    	optf = optf + 1;		
    }
    
    break;
  case is_MinusSca:
    /* Code for MinusSca Goes Here */
    optr = OP_MINUS;
    if((_p_->u.minussca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.minussca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_MINUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.minussca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.minussca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.minussca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_MINUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.minussca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_MINUS;
    	++j; 		 
    	optf = optf + 1;			
    }
    
    break;
  case is_MulSca:
    /* Code for MulSca Goes Here */
    optr = OP_MULTIPLY;	
    
    if((_p_->u.mulsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.mulsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_MULTIPLY;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.mulsca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.mulsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.mulsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_MULTIPLY;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.mulsca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_MULTIPLY;
    	++j; 		
    	optf = optf + 1;			
    }
    
    break;
  case is_DivSca:
   /* Code for DivSca Goes Here */
    optr = OP_DIVIDE;
    
    if((_p_->u.divsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.divsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_DIVIDE;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.divsca_.scalar_exp_1);
    
    if((flag == false) && ((_p_->u.divsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.divsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_DIVIDE;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.divsca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_DIVIDE;
    	++j; 		
    	optf = optf + 1;		
    }
    
    break;
  case is_ModSca:
    /* Code for ModSca Goes Here */
    optr = OP_MODULUS;
    
    if((_p_->u.modsca_.scalar_exp_1->kind == is_RefSca) || (_p_->u.modsca_.scalar_exp_1->kind == is_AtomSca))
    {
    	optrarray[j] = OP_MODULUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.modsca_.scalar_exp_1);
    visitMod(_p_->u.modsca_.mod_);
    
    if((flag == false) && ((_p_->u.modsca_.scalar_exp_2->kind != is_RefSca) ||
    					   (_p_->u.modsca_.scalar_exp_2->kind != is_AtomSca)))
    {
    	optrarray[j] = OP_MODULUS;
    	++j; 		
    	optf = optf + 1;   	
    	flag = true;
    }
    
    visitScalar_Exp(_p_->u.modsca_.scalar_exp_2);
    
    if(!flag)
    {
    	optrarray[j] = OP_MODULUS;
    	++j; 		 
    	optf = optf + 1;		
    }
    break;
  case is_NotSca:
    /* Code for NotSca Goes Here */
    visitScalar_Exp(_p_->u.notsca_.scalar_exp_);
    break;
  case is_AtomSca:
    /* Code for AtomSca Goes Here */
    visitAtom(_p_->u.atomsca_.atom_);
    break;
  case is_RefSca:
    /* Code for RefSca Goes Here */
    visitReference(_p_->u.refsca_.reference_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Scalar_Exp!\n");
    exit(1);
  }
}

void visitAtom(Atom _p_)
{
  switch(_p_->kind)
  {
  case is_AtmInt:
    /* Code for AtmInt Goes Here */
    n = (int)_p_->u.atmint_.integer_;
    snprintf(str, MAX_DIGITS+1, "%d", n);
    if (bw)	
    {       
		if(r1==-1)
		{
			r1=(long)n;
			cfilter = m->setFilter1(opcname, OP_GT, (char *)str, total, counter);
			counter = counter + 2;
			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
		}		
		else 
		r2=(long)n;
		if(r2 != -1)
		{	
			cfilter = m->setFilter1(opcname, OP_LT, (char *)str, total, counter);
			counter = counter + 2; 	
			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
		}	

    }
    else
    {	
	if (optf==1)
	{	
    		cfilter = m->setFilter1(opcname, optr, (char *)str, total, counter);
    		counter = counter + 2; 
  			--optf;
    		if(cfilter == NULL)
    		{
    			free(newnode);
    			free_table();
    			exit(1);
    		}
        }
	if (optf > 1)
	{    
		while(optf != 0)
		{       
            NODE *enode;
			enode = (NODE *)malloc(sizeof(NODE));
			memset(enode, 0, sizeof(enode));
			enode->nodeIndex = optf;
           		enode->name=opcarray[i-1];
			enode->optr=optrarray[j-1];
			if (basenode == NULL)
				{
				enode->value=(NODE *)str;
				enode->node_type=0;
				basenode = enode;
				}
			else
				{
				enode->value=basenode;
				enode->node_type=1;
				basenode = enode;
				} 
			cfilter = m->setFilter3(basenode->name, basenode->optr, basenode, total, counter);
    			counter = counter + 2; 
    			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
			--i;
			--j;
			--optf;
		}	
	   }	
	}			
    atmop=1; 
    visitInteger(_p_->u.atmint_.integer_);
    break;
  case is_AtmDbl:
    /* Code for AtmDbl Goes Here */
    visitDouble(_p_->u.atmdbl_.double_);
    break;
  case is_AtmStr:
    /* Code for AtmStr Goes Here */
   if (optf==1)
	{	
    		cfilter = m->setFilter1(opcname, optr, (char *)_p_->u.atmstr_.string_, total, counter);
    		counter = counter + 2; 
  			--optf;
    		if(cfilter == NULL)
    		{
    			free(newnode);
    			free_table();
    			exit(1);
    		}
   }
	if (optf > 1)
	{    
		while(optf != -1)
		{       
            NODE *enode;
			enode = (NODE *)malloc(sizeof(NODE));
			memset(enode, 0, sizeof(enode));
			enode->nodeIndex = optf;
            enode->name=opcarray[i-1];
			enode->optr=optrarray[j];
			if (basenode == NULL)
			{
				enode->value=(NODE *)str;
				enode->node_type=0;
				basenode = enode;
			}
			else
			{
				enode->value=basenode;
				enode->node_type=1;
				basenode = enode;
			} 
			cfilter = m->setFilter3(basenode->name, basenode->optr, basenode, total, counter);
    		counter = counter + 2; 
    		if(cfilter == NULL)
    		{
    			free(newnode);
    			free_table();
    			exit(1);
    		}
			--i;
			--j;
			--optf;
		}	
	   }	
				
    atmop=1;  
   visitString(_p_->u.atmstr_.string_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Atom!\n");
    exit(1);
  }
}

void visitComparison(Comparison _p_)
{
  switch(_p_->kind)
  {
  case is_Eq:
    /* Code for Eq Goes Here */
    optr = OP_EQ;
    optrarray[j] = optr;
    ++j; 		 
    optf = optf + 1;	
    break;
  case is_Neq:
    /* Code for Neq Goes Here */
    optr = OP_NEQ;
    optrarray[j] = optr;
    ++j; 		
    optf = optf + 1;
    break;
  case is_Gt:
    /* Code for Gt Goes Here */
    optr = OP_GT; 
    optrarray[j] = optr;
    ++j; 		
    optf = optf + 1;	
    break;
  case is_Lt:
    /* Code for Lt Goes Here */
    optr = OP_LT;
    optrarray[j] = optr;
    ++j; 		
    optf = optf + 1; 	
    break;
  case is_Ge:
    /* Code for Ge Goes Here */
     optr = OP_GTE;
     optrarray[j] = optr;
    ++j; 		
     optf = optf + 1;	
    break;
  case is_Le:
    /* Code for Le Goes Here */
    optr = OP_LTE;
    optrarray[j] = optr;
    ++j; 		 
    optf = 1;
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Comparison!\n");
    exit(1);
  }
}

void visitOptional_Group_By_Clause(Optional_Group_By_Clause _p_)
{
  switch(_p_->kind)
  {
  case is_NoGrpBy:
    /* Code for NoGrpBy Goes Here */
    break;
  case is_GrpBy:
    /* Code for GrpBy Goes Here */
    visitGroup(_p_->u.grpby_.group_);
    visitBy(_p_->u.grpby_.by_);
    visitColumn_Reference_List(_p_->u.grpby_.column_reference_list_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Optional_Group_By_Clause!\n");
    exit(1);
  }
}

void visitOptional_Having_Clause(Optional_Having_Clause _p_)
{
  switch(_p_->kind)
  {
  case is_NoHvng:
    /* Code for NoHvng Goes Here */
    break;
  case is_Hvng:
    /* Code for Hvng Goes Here */
    visitHaving(_p_->u.hvng_.having_);
    visitCondition(_p_->u.hvng_.condition_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Optional_Having_Clause!\n");
    exit(1);
  }
}

void visitOptional_Order_By_Clause(Optional_Order_By_Clause _p_)
{
  switch(_p_->kind)
  {
  case is_NoOrdBy:
    /* Code for NoOrdBy Goes Here */
    break;
  case is_OrdBy:
    /* Code for OrdBy Goes Here */
    visitOrder(_p_->u.ordby_.order_);
    visitBy(_p_->u.ordby_.by_);
    visitColumn_Reference_Ordering_List(_p_->u.ordby_.column_reference_ordering_list_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Optional_Order_By_Clause!\n");
    exit(1);
  }
}

void visitColumn_Reference_List(Column_Reference_List _p_)
{
  switch(_p_->kind)
  {
  case is_SglColRef:
    /* Code for SglColRef Goes Here */
    visitColumn_Reference(_p_->u.sglcolref_.column_reference_);
    break;
  case is_MulColRef:
    /* Code for MulColRef Goes Here */
    visitColumn_Reference_List(_p_->u.mulcolref_.column_reference_list_);
    visitColumn_Reference(_p_->u.mulcolref_.column_reference_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Column_Reference_List!\n");
    exit(1);
  }
}

void visitColumn_Reference_Ordering_List(Column_Reference_Ordering_List _p_)
{
  switch(_p_->kind)
  {
  case is_SglColRefOrd:
    /* Code for SglColRefOrd Goes Here */
    visitColumn_Reference_Ordering(_p_->u.sglcolreford_.column_reference_ordering_);
    break;
  case is_MulColRefOrd:
    /* Code for MulColRefOrd Goes Here */
    visitColumn_Reference_Ordering_List(_p_->u.mulcolreford_.column_reference_ordering_list_);
    visitColumn_Reference_Ordering(_p_->u.mulcolreford_.column_reference_ordering_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Column_Reference_Ordering_List!\n");
    exit(1);
  }
}

void visitColumn_Reference_Ordering(Column_Reference_Ordering _p_)
{
  switch(_p_->kind)
  {
  case is_ColRefOrd:
    /* Code for ColRefOrd Goes Here */
    visitColumn_Reference(_p_->u.colreford_.column_reference_);
    visitOptional_Ordering(_p_->u.colreford_.optional_ordering_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Column_Reference_Ordering!\n");
    exit(1);
  }
}

void visitOptional_Ordering(Optional_Ordering _p_)
{
  switch(_p_->kind)
  {
  case is_NoOrd:
    /* Code for NoOrd Goes Here */
    break;
  case is_AscOrd:
    /* Code for AscOrd Goes Here */
    visitAsc(_p_->u.ascord_.asc_);
    break;
  case is_DescOrd:
    /* Code for DescOrd Goes Here */
    visitDesc(_p_->u.descord_.desc_);
    break;

  default:
    fprintf(stderr, "Error: bad kind field when printing Optional_Ordering!\n");
    exit(1);
  }
}

void visitSelect(SELECT p)
{
  /* Code for SELECT Goes Here */
}
void visitFrom(FROM p)
{
  /* Code for FROM Goes Here */
}
void visitDistinct(DISTINCT p)
{
  /* Code for DISTINCT Goes Here */
}
void visitWhere(WHERE p)
{
  /* Code for WHERE Goes Here */
}
void visitAs(AS p)
{
  /* Code for AS Goes Here */
}
void visitMod(MOD p)
{
  /* Code for MOD Goes Here */
}
void visitNot(NOT p)
{     
      if ((exp) && (bw==0))
      {        
                pop();  
                boolop=0; 
		logicarry[boolop]=OP_NOT;
      		++boolop;
      }
      if ((exp) && (bw==1))
      {
       		logicarry[boolop]=OP_NOT;
      		++boolop;
      }
      if (exp==0) 
      {			 		
      		m->setFilter1(NULL, OP_NOT, NULL, total, logiccounter); 
  		++logiccounter;
      } 	
      
      
 /* Code for NOT Goes Here */
}
void visitAnd(AND p)
{
    
      if ((exp) && (bw==0))
      {        
                if ((atmop == 0) && (optf >=1) || (optf >=1) && (logiccounter > 0))
	 {   
	        while(optf != -1)
		{
			NODE *enode;
			enode = (NODE *)malloc(sizeof(NODE));
			memset(enode, 0, sizeof(enode));
			enode->nodeIndex = optf;
            enode->name=opcarray[i-1];
			enode->optr=OP_NONE;
			if (basenode == NULL)
			{
				enode->value=NULL;
				enode->node_type=1;
				basenode = enode;
			}
			else
			{	
				enode->name=opcarray[i-1];
				enode->optr=optrarray[j];
				enode->node_type=1;
				enode->value=basenode;
				basenode = enode;
			} 
			cfilter = m->setFilter3(basenode->name, basenode->optr, basenode, total, counter);
    			counter = counter + 2; 
    			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
			--i;
			--j;
			--optf;
			
		}	
	   }	  
                pop();  
                boolop=0; 
                optf=0;
		i=0;
		j=0;
		logicarry[boolop]=OP_AND;
      		++boolop;
      }
      if ((exp) && (bw==1))
      {
       		logicarry[boolop]=OP_AND;
      		++boolop;
 			 
      }
      if (exp==0)
      {			 		
      		m->setFilter1(NULL, OP_AND, NULL, total, logiccounter);
      		++logiccounter;
      } 
	  	
  /* Code for AND Goes Here */
}
void visitOr(OR p)
{
     if ((exp) && (bw==0))
      {        
                if ((atmop == 0) && (optf >=1) || (optf >=1) && (logiccounter > 0))
	 {   
	        while(optf != -1)
		{
			NODE *enode;
			enode = (NODE *)malloc(sizeof(NODE));
			memset(enode, 0, sizeof(enode));
			enode->nodeIndex = optf;
            enode->name=opcarray[i-1];
			enode->optr=OP_NONE;
			if (basenode == NULL)
			{
				enode->value=NULL;
				enode->node_type=1;
				basenode = enode;
			}
			else
			{	
				enode->name=opcarray[i-1];
				enode->optr=optrarray[j];
				enode->node_type=1;
				enode->value=basenode;
				basenode = enode;
			} 
			cfilter = m->setFilter3(basenode->name, basenode->optr, basenode, total, counter);
    			counter = counter + 2; 
    			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
			--i;
			--j;
			--optf;
			
		}	
	   }	 
                pop();  
                boolop=0; 
		optf=0;
 		i=0;
		j=0;
		logicarry[boolop]=OP_OR;
      		++boolop;
      }
      if ((exp) && (bw==1))
      {
       		logicarry[boolop]=OP_OR;
      		++boolop;
                
      }
      if (exp==0)
      {			 		
      		m->setFilter1(NULL, OP_OR, NULL, total, logiccounter); 
  		++logiccounter;
      } 
        	
  /* Code for OR Goes Here */
}

void pop ()
{
  while (boolop != -1)
			{
				m->setFilter1(NULL, logicarry[boolop-1], NULL, total, logiccounter);
      				++logiccounter;
				--boolop;	
			}
  
}

void visitIn(IN p)
{
  /* Code for IN Goes Here */
}
void visitLike(LIKE p)
{
  /* Code for LIKE Goes Here */
}
void visitBetween(BETWEEN p)
{
  	
  /* Code for BETWEEN Goes Here */
}
void visitExists(EXISTS p)
{
  /* Code for EXISTS Goes Here */
}
void visitSum(SUM p)
{
    funcname="Sum";	
  /* Code for SUM Goes Here */
}
void visitMax(MAX p)
{
   funcname="Max";	
  /* Code for MAX Goes Here */
}
void visitMin(MIN p)
{
   funcname = "Min";	
  /* Code for MIN Goes Here */
}
void visitAvg(AVG p)
{
  funcname = "Avg";	
  /* Code for AVG Goes Here */
}
void visitCount(COUNT p)
{
   funcname = "Count"; 
  /* Code for COUNT Goes Here */
}
void visitGroup(GROUP p)
{
  /* Code for GROUP Goes Here */
}
void visitBy(BY p)
{
  /* Code for BY Goes Here */
}
void visitOrder(ORDER p)
{
  /* Code for ORDER Goes Here */
}
void visitHaving(HAVING p)
{
  /* Code for HAVING Goes Here */
}
void visitAsc(ASC p)
{
  /* Code for ASC Goes Here */
}
void visitDesc(DESC p)
{
  /* Code for DESC Goes Here */
}
void visitIdentifier(IDENTIFIER p)
{
  /* Code for IDENTIFIER Goes Here */
}
void visitInvalid(INVALID p)
{
  /* Code for INVALID Goes Here */
}
void visitSc(SC p)
{
  /* Code for SC Goes Here */
   if ((atmop == 0) && (optf >=1) || (optf >=1) && (logiccounter > 0))
	 {   
	        while(optf != -1)
		{
			NODE *enode;
			enode = (NODE *)malloc(sizeof(NODE));
			memset(enode, 0, sizeof(enode));
			enode->nodeIndex = optf;
            enode->name=opcarray[i-1];
			enode->optr=OP_NONE;
			if (basenode == NULL)
			{
				enode->value=NULL;
				enode->node_type=1;
				basenode = enode;
			}
			else
			{	
				enode->name=opcarray[i-1];
				enode->optr=optrarray[j];
				enode->node_type=1;
				enode->value=basenode;
				basenode = enode;
			} 
			cfilter = m->setFilter3(basenode->name, basenode->optr, basenode, total, counter);
    			counter = counter + 2; 
    			if(cfilter == NULL)
    			{
    				free(newnode);
    				free_table();
    				exit(1);
    			}
			--i;
			--j;
			--optf;
			
		}	
	   }		
}
void visitIdent(Ident i)
{
  /* Code for Ident Goes Here */
}
void visitInteger(Integer i)
{
  /* Code for Integer Goes Here */
}
void visitDouble(Double d)
{
  /* Code for Double Goes Here */
}
void visitChar(Char c)
{
  /* Code for Char Goes Here */
}
void visitString(String s)
{
  /* Code for String Goes Here */
}

